package com.sunshine.util;

import com.sunshine.bean.User;
import com.sunshine.exception.InvalidJwtTokenException;
import com.sunshine.exception.InvalidUserException;
import com.sunshine.model.UserMapper;
import com.sunshine.security.JsonWebToken;
import io.jsonwebtoken.ExpiredJwtException;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

import static java.util.Optional.ofNullable;

/**
 * Created by along on 4/20/18.
 */
@Component
public class Requests {
    private static final Logger LOGGER = ESLoggerFactory.getLogger(Requests.class);

    @Autowired
    private UserMapper userMapper;

    public static int getId(HttpServletRequest request) throws InvalidJwtTokenException {
        try {
            return JsonWebToken.getSubjectFromRequest(request)
                    .map(Integer::parseInt)
                    .orElseThrow(() -> new InvalidJwtTokenException("Not found Token"));
        } catch (InvalidJwtTokenException | NumberFormatException | ExpiredJwtException e) {
            LOGGER.warn("Requests.getId() error {}", e.getMessage());
            throw new InvalidJwtTokenException(e.getMessage());
        }
    }

    public static int getId(String token) throws InvalidJwtTokenException {
        try {
            return JsonWebToken.getSubjectFromToken(token)
                    .map(Integer::parseInt)
                    .orElseThrow(() -> new InvalidJwtTokenException("Not found Token"));
        } catch (InvalidJwtTokenException | NumberFormatException | ExpiredJwtException e) {
            LOGGER.warn("Requests.getId() error {}", e.getMessage());
            throw new InvalidJwtTokenException(e.getMessage());
        }
    }

    public Optional<User> getUser(HttpServletRequest request) throws InvalidJwtTokenException, InvalidUserException {
        User user = userMapper.findById(getId(request));
        if (user == null) {
            LOGGER.warn("notice: a dangerous question from {}", request.getRemoteAddr());
            throw new InvalidUserException("notice: a dangerous question");
        }
        return ofNullable(user);
    }

    public User getUser(String token) throws InvalidJwtTokenException {
        User user = userMapper.findById(getId(token));

        if (user == null) {
            throw new InvalidJwtTokenException();
        }

        return user;
    }
}
